`timescale    1ns/100ps
module sys_comm#(
parameter [31:0] VERSION_DATE     =  32'h19_07_08_16,
parameter [7:0]  MAIN_FUNCTION    =  "S",
parameter [7:0]  SUB_FUNCTION     =  "A",
parameter [7:0]  MAIN_SOLUTION    =  1,
parameter [7:0]  SUB_SOLUTION     =  2,
parameter [7:0]  APPLICATION_TYPE =  "G",
parameter [7:0]  MAIN_VERSION     =  1,
parameter [7:0]  SUB_VERSION      =  0,
parameter [7:0]  MINI_VERSION     =  0,

parameter        DEVICE_TYPE      =  0,
parameter [23:0] FLASH_BIAS       =  24'hB1CE6

)
(
    input       wire            sclkin      ,  //25m
    input       wire            resetb      ,
    input       wire            sclk        , //125m
    
    input       wire            JTCK        ,
    input       wire            JTDI        ,
    input       wire            JTMS        ,
    output      wire            JTDO        ,

    output      wire            flash_SCK   ,
    output      wire            flash_CS_n  ,
    inout       tri             FLASH_SI    ,
    inout       tri             FLASH_SO    ,

    //接收命令  
    input       wire            rec_flag    ,
    input       wire            rec_error   ,
    input       wire [7:0]      rec_data    ,
    input       wire [1:0]      rec_vendor  , //0:无效包 1：UDP包
        
    input       wire [1:0]      gp0_rx_type ,
    input       wire [1:0]      gp1_rx_type ,
    
    output      wire            send_flag   ,
    output      wire            pre_flag    ,
    output      wire [7:0]      send_data   ,
    input       wire            blank_flag  ,
    input       wire            redu_flag   ,
    
    //显示设置
    input       wire            lock_enable ,
    input       wire            locked      ,
    
    input       wire            time_1ms_sync   ,
    input       wire            time_1s_sync    ,
    input       wire            time_15ms_sync  ,
    input       wire            time_250ms_sync ,
    
    //phy 接口
    output      wire            phy_rst_mcu     ,
    output      wire            mdc             ,
    inout       tri             mdio            ,
    
    input       wire            sdram_ready     ,
    input       wire            sdram_busy      ,
        
    output      reg             init_mode       ,
    output      reg             comm_en         ,
    
    input       wire [3:0]      pll_reset_cnt   ,
    
    output      reg             reconfig_pll_en ,
    
    input       wire            frame_start     ,
    input       wire            key_in          ,
        
    input       wire            kp_busy         ,
          
    output wire [3:0]       apb_sel              ,
    output wire [31:0]      apb_addr             ,
    output wire             apb_rw_en            ,
    output wire [31:0]      apb_wdata            ,

    input  wire [31:0]      apb_rdata1           ,
    input  wire [31:0]      apb_rdata2           

);

wire            clk_mcu     ; //62.5m

//**************************************************************
//        通讯数据处理/上电初始化
//**************************************************************

wire [31:0]      apb_rdata0      ;
wire [31:0]      apb_rdata3      ;     

wire [3:0]       sel              ;
wire [31:0]      addr             ;
wire             rw_en            ;
wire [31:0]      wdata            ;
wire [31:0]      rdata0           ;
wire [31:0]      rdata1           ;
wire [31:0]      rdata2           ;
wire [31:0]      rdata3           ;


wire [7:0]  GPIO0_I              ;
wire [7:0]  GPIO0_O              ;
wire [7:0]  nGPEN0               ;
wire [7:0]  GPIO1_I              ;
wire [7:0]  GPIO1_O              ;
wire [7:0]  nGPEN1               ;
wire [7:0]  GPIO2_I              ;
wire [7:0]  GPIO2_O              ;
wire [7:0]  nGPEN2               ;

    
wire                O_INI_IP        ;
    
wire                EXT_RAM_EN      ;
wire                EXT_RAM_WR      ;
wire    [3:0]       EXT_RAM_BYTE_EN ;
wire    [13:0]      EXT_RAM_ADDR    ;
wire    [31:0]      EXT_RAM_WDATA   ;
wire    [31:0]      EXT_RAM_RDATA   ;

reg                 reconfig_pll_en_dly ;
reg                 reboot_en       ;
reg                 reboot_wr_en    ;
reg                 ext_cfg_wr      ;
reg                 reboot_flag     ;
reg     [1:0]       reboot_cnt      ;
reg                 reboot_en_tmp   ;

wire                packet_load     ;
wire                fpga_rec_flag   ;
reg                 mcu_rec_end     ;
reg     [1:0]       fpga_flag_next  ;



///////////////////////////////////////////////////////////////
mcu_top #(
    .FLASH_BIAS (   FLASH_BIAS  )
)
mcu_top
(
    .sclk                   (   sclk                        ),
    .clk_mcu                (   clk_mcu                     ),
    .resetb                 (   resetb                      ),

    .UART_RXD               (                               ),
    .UART_CTS_n             (                               ),
    .UART_TXD               (                               ),
    .UART_RTS_n             (                               ),

    .JTRST_n                (   1'b1                        ),
    .JTCK                   (   JTCK                        ),
    .JTDI                   (   JTDI                        ),
    .JTMS                   (   JTMS                        ),
    .JTDO                   (   JTDO                        ),

    .EXT_RAM_EN             (   EXT_RAM_EN                  ),
    .EXT_RAM_WR             (   EXT_RAM_WR                  ),
    .EXT_RAM_ADDR           (   EXT_RAM_ADDR                ),
    .EXT_RAM_BYTE_EN        (   EXT_RAM_BYTE_EN             ),
    .EXT_RAM_WDATA          (   EXT_RAM_WDATA               ),
    .EXT_RAM_RDATA          (   EXT_RAM_RDATA               ),


    .FLASH_SCK              (   flash_SCK                   ),
    .FLASH_CS_N             (   flash_CS_n                  ),
    
    .FLASH_SI               (   FLASH_SI                    ),
    .FLASH_SO               (   FLASH_SO                    ),
    
    .GPIO0_I                ( GPIO0_I          ),
    .GPIO0_O                ( GPIO0_O          ),
    .nGPEN0                 ( nGPEN0           ),
    .GPIO1_I                ( GPIO1_I          ),
    .GPIO1_O                ( GPIO1_O          ),
    .nGPEN1                 ( nGPEN1           ),
    .GPIO2_I                ( GPIO2_I          ),
    .GPIO2_O                ( GPIO2_O          ),
    .nGPEN2                 (   nGPEN2                      ),
    .O_INI_IP               (   O_INI_IP                    ),
    
    
    .apb_sel                (   sel                     ),
    .apb_addr               (   addr                    ),
    .apb_rw_en              (   rw_en                   ),
    .apb_wdata              (   wdata                   ),
    .apb_rdata0             (   apb_rdata0                  ),
    .apb_rdata1             (   apb_rdata1                  ),
    .apb_rdata2             (   'd0                         ),
    .apb_rdata3             (   apb_rdata3                  )
) ;

v8_com_ctrl_mcu_04
#(
    .DEVICE_TYPE(DEVICE_TYPE)
) com_ctrl(

    .resetb                 (   resetb                              ),
    .sclk                   (   sclk                                ),
    .comm_en                (   comm_en                             ),

    .rec_flag               (   rec_flag                            ),
    .rec_error              (   rec_error                           ),
    .rec_data               (   rec_data                            ),
    .rec_vendor             (   rec_vendor                          ),

    .send_flag              (   send_flag                           ),
    .pre_flag               (   pre_flag                            ),
    .send_data              (   send_data                           ),

    .blank_flag             (   blank_flag                          ),
    .redu_flag              (   redu_flag                           ),
    .time_1ms_sync          (   time_1ms_sync                       ),

    .clk_mcu                (   clk_mcu                             ), //62.5M

    .EXT_RAM_EN             (   EXT_RAM_EN                          ),
    .EXT_RAM_WR             (   EXT_RAM_WR                          ),
    .EXT_RAM_BYTE_EN        (   EXT_RAM_BYTE_EN                     ),
    .EXT_RAM_ADDR           (   EXT_RAM_ADDR                        ),
    .EXT_RAM_WDATA          (   EXT_RAM_WDATA                       ),
    .EXT_RAM_RDATA          (   EXT_RAM_RDATA                       ),

    .packet_load            (   packet_load                         ),
    .interrupt              (   fpga_rec_flag                       ),

    .mcu_rec_end            (   mcu_rec_end                         ),
    .fpga_flag_next         (   fpga_flag_next                      )
    );


//系统状态数据生成
state_ctrl_02
#(
    .MAIN_FUNCTION    (MAIN_FUNCTION   ),
    .SUB_FUNCTION     (SUB_FUNCTION    ),
    .MAIN_SOLUTION    (MAIN_SOLUTION   ),
    .SUB_SOLUTION     (SUB_SOLUTION    ),
    .APPLICATION_TYPE (APPLICATION_TYPE),
    .MAIN_VERSION     (MAIN_VERSION    ),
    .SUB_VERSION      (SUB_VERSION     ),
    .MINI_VERSION     (MINI_VERSION    ),
    .VERSION_DATE     (VERSION_DATE    )
) state_ctrl(
    .resetb                 (   resetb          ),
    .sclk                   (   sclk            ),

    //设置总线接口
    .packet_load            (   packet_load     ),
    .fpga_rec_flag          (   fpga_rec_flag   ),
    
    .apb_sel                (   sel                     ),
    .apb_addr               (   addr                    ),
    .apb_rw_en              (   rw_en                   ),
    .apb_wdata              (   wdata                   ),
    .apb_rdata0             (   apb_rdata0              ),
    
    //千兆PHY接口,包错误统计
    .rec_flag               (   rec_flag        ),
    .rec_error              (   rec_error       ),

    //
    .gp0_rx_type            (   gp0_rx_type     ),
    .gp1_rx_type            (   gp1_rx_type     ),
    //
    .lock_enable            (   lock_enable     ),
    .locked                 (   locked          ),

    .pll_reset_cnt          (   pll_reset_cnt   )


);


sys_reboot sys_reboot(
    .resetb         (resetb         ),
    .sclk           (sclk           ), //125m
    .time_1s_sync   (time_1s_sync   ),
    .apb_sel        (sel        ),
    .apb_addr       (addr       ),
    .apb_rw_en      (rw_en      ),
    .apb_wdata      (wdata      )
);

assign mdc = GPIO2_O[1];
assign mdio = nGPEN2[2] ? 1'bZ : GPIO2_O[2];
assign GPIO2_I[2] = mdio;
assign phy_rst_mcu  = GPIO2_O[3];
assign GPIO2_I[7] = sdram_ready ;
assign GPIO2_I[4] = fpga_rec_flag ;


//帧开始 中断， 60hz 16.67ms
reg [3:0] frame_start_reg;
always@(posedge sclk or negedge resetb)begin
    if ( resetb == 0 )
        frame_start_reg[3:0] <= 4'b0;
    else if( frame_start )
        frame_start_reg[3:0] <= frame_start_reg[3:0] + 1'b1 ;
end
assign GPIO2_I[5] = frame_start_reg[2] ;

//按键
reg [1:0]key_cnt;
always @(posedge sclk or negedge resetb) begin
    if (!resetb)
        key_cnt <= 'b0;
    else if( key_in )
        key_cnt <= 'b0;
    else if( key_cnt[1]==0 && time_15ms_sync )
        key_cnt <= key_cnt + 1;
    else 
        key_cnt <= key_cnt ;
end

assign GPIO2_I[6] = key_cnt[1] ;


always @(posedge sclk or negedge resetb) begin
    if (!resetb)
        ext_cfg_wr <= 1'b0;
    else if (apb_sel[0] && apb_addr[27:16]==12'h200 && apb_rw_en)
        ext_cfg_wr <= 1'b1;
    else 
        ext_cfg_wr <= 1'b0;
end

//************************************************/
//        reconfig_pll_en
//************************************************/
always@(posedge sclk or negedge resetb)
    if (resetb == 0)
        reconfig_pll_en <=0;
    else if (reconfig_pll_en_dly)
        reconfig_pll_en<=0;
    else if (ext_cfg_wr == 1 && apb_addr[7:2] == 6'h01)
        reconfig_pll_en<=apb_wdata[24];

always@(posedge sclk)
    reconfig_pll_en_dly <= reconfig_pll_en;


reg  [31:0]state_reg;
assign apb_rdata3 = state_reg;
always @(posedge sclk or negedge resetb)begin
    if (resetb == 0)
        state_reg <= 0 ;
    else if ( apb_sel[3] )
        case(apb_addr[7:0])
            8'h00: begin
                        state_reg[0] <= sdram_busy ;
                        state_reg[7:1] <= 1'b0 ;
                        state_reg[8] <= kp_busy ;
                        state_reg[15:9] <= 1'b0 ;
                        state_reg[31:16] <= 16'b0 ;
                   end
            default state_reg<='d0;
        endcase
end


/******************************************************/
//系统状态 在ahb   0xa700_0000
/******************************************************/
reg sys_state_wr;
always @(posedge sclk or negedge resetb) begin
    if (!resetb)
        sys_state_wr <= 1'b0;
    else if (apb_sel[0] && apb_addr[27:16]==12'h700 && apb_rw_en)
        sys_state_wr <= 1'b1;
    else 
        sys_state_wr <= 1'b0;
end
always@(posedge sclk  or negedge resetb)begin
    if (resetb == 0)
        init_mode <= 0;
    else if (sys_state_wr && apb_addr[3:0] == 4'b0 )
        init_mode <= apb_wdata[0];
end

always@(posedge sclk or negedge resetb)begin
    if (resetb == 0)
        comm_en <= 0;
    else if (sys_state_wr && apb_addr[3:0] == 4'd4 )
        comm_en <= apb_wdata[0];
end

/******************************************************/
//com_ctrl控制   在ahb   0xa600_0000
/******************************************************/
reg com_ctrl_wr;
always @(posedge sclk or negedge resetb) begin
    if (!resetb)
        com_ctrl_wr <= 1'b0;
    else if (apb_sel[0] && apb_addr[27:16]==12'h600 && apb_rw_en)
        com_ctrl_wr <= 1'b1;
    else 
        com_ctrl_wr <= 1'b0;
end
always@(posedge sclk  or negedge resetb)begin
    if (resetb == 0)
        fpga_flag_next <= 0;
    else if (com_ctrl_wr && apb_addr[3:0] == 4'b0 )
        fpga_flag_next <= apb_wdata[1:0];
end

always@(posedge sclk  or negedge resetb)begin
    if (resetb == 0)
        mcu_rec_end <= 0;
    else if (com_ctrl_wr && apb_addr[3:0] == 4'd0 )
        mcu_rec_end    <= 1 ;
    else
        mcu_rec_end    <=  0;
end


my_count u_my_count(

    .clk(clk_mcu),
    .rst_n(1'b1),
    .q({GPIO1_I,GPIO0_I})
);


assign apb_sel       = sel      ;
assign apb_addr      = addr     ;
assign apb_rw_en     = rw_en    ;
assign apb_wdata     = wdata    ;




endmodule
`default_nettype wire